package com.osfw.activiti.service.process.impl;

import com.osfw.activiti.domain.*;
import com.osfw.activiti.entity.history.ActHiProcinst;
import com.osfw.activiti.entity.resource.ActReProcdef;
import com.osfw.activiti.enums.ProcApprovalResult;
import com.osfw.activiti.enums.ProcExecResult;
import com.osfw.activiti.enums.ProcUserType;
import com.osfw.activiti.service.history.IActHiCommentService;
import com.osfw.activiti.service.history.IActHiProcinstService;
import com.osfw.activiti.service.process.IProcessService;
import com.osfw.activiti.service.resource.IActReProcdefService;
import com.osfw.activiti.service.running.IActRuExecService;
import com.osfw.activiti.service.running.IActRuTaskService;
import com.osfw.activiti.service.running.IActRuUserService;
import com.osfw.activiti.service.running.IActRuVarService;
import com.osfw.system.entity.manage.SysUser;
import com.osfw.system.service.manage.ISysDeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 流程综合业务 服务层实现
 */
@Service
public class ProcessServiceImpl implements IProcessService {

    @Autowired
    private IActReProcdefService procdefService;
    @Autowired
    private IActHiProcinstService procinstService;
    @Autowired
    private IActRuUserService ruUserService;
    @Autowired
    private IActRuExecService ruExecService;
    @Autowired
    private IActRuTaskService ruTaskService;
    @Autowired
    private IActRuVarService ruVarService;
    @Autowired
    private IActHiCommentService hiCommentService;
    @Autowired
    private ISysDeptService sysDeptService;


    @Override
    @Transactional
    public ActHiProcinst apply(ProcessApplyInfo applyInfo) {
        Date startTime = new Date();
        // 获取最新版本的流程信息
        ActReProcdef procdef = procdefService.getLatestVersionProcdefByProcKey(applyInfo.getProcKey());
        // 获取流程开始节点信息
        ProcessNodeInfo startNode = procdefService.getStartNodeInfo(procdef);
        // 获取流程下个节点信息
        ProcessNodeInfo nextNode = procdefService.getNextNodeInfo(procdef, startNode.getKey());

        // 初始化实例化表数据
        ActHiProcinst procinst = procinstService.init(applyInfo.getTitle(), applyInfo.getBusiType(), applyInfo.getBusiKey(), applyInfo.getStartUser(), startTime, procdef, nextNode);
        // 初始化流程执行数据
        ProcessExecResult execResult = ruExecService.init(procinst, startNode, startTime, applyInfo.getStartUser(), nextNode);
        // 初始化任务执行数据
        ruTaskService.init(execResult);
        // 初始化流程全局变量
        ruVarService.addGlobalVariables(procinst.getProcInstId(), applyInfo.getVariables());
        // 初始化流程关联用户
        applyInfo.getStartUser().getParams().put("userType", ProcUserType.STARTER.getCode());
        nextNode.getAssignees().stream().forEach(x -> x.getParams().put("userType", ProcUserType.ASSIGNEE.getCode()));
        nextNode.getAssignees().add(applyInfo.getStartUser());
        ruUserService.addProcUserinst(procdef.getProcDefId(), procinst.getProcInstId(), nextNode.getAssignees());

        return procinst;
    }

    @Override
    @Transactional
    public boolean complete(ProcessApproval approval, SysUser sysUser) {
        // 获取当前时间（办理时间）
        Date currentTime = new Date();
        // 获取审批结果
        ProcApprovalResult result = ProcApprovalResult.getProcApprovalResult(approval.getResult());
        // 流转执行实例
        ProcessExecResult execResult = null;
        switch (result) {
            case AGREE: // 注：会签节点全部审批完成，且全部同意，则继续往下流转流程
                // 流程执行
                execResult = ruExecService.agree(approval, sysUser, currentTime);
                // 流程任务
                ruTaskService.agree(approval, sysUser, currentTime, execResult);
                break;
            case DISAGREE: // 注：会签节点全部审批完成，且存在一个不同意，则结束该流程实例
                // 流程执行
                execResult = ruExecService.disagree(approval, sysUser, currentTime);
                // 流程任务
                ruTaskService.disagree(approval, sysUser, currentTime, execResult);
                // 流程实例
                if(execResult.getResult().intValue() == ProcExecResult.PROCESS_ENDED.getResult().intValue()){
                    procinstService.finish(approval, sysUser, currentTime, execResult);
                }
                break;
            case GOBACK: // 注：会签节点没有回退功能
                // 流程执行回退
                execResult = ruExecService.goback(approval, sysUser, currentTime);
                // 流程任务回退
                ruTaskService.goback(approval, sysUser, currentTime, execResult);
                break;
        }
        // 添加流程意见数据
        hiCommentService.addProcComment(approval, sysUser, currentTime);
        // 添加流程全局变量
        ruVarService.addGlobalVariables(approval.getProcInstId(), approval.getGlobalVariables());
        // 添加流程局部变量
        ruVarService.addLocalVariables(approval.getProcInstId(), approval.getProcExecId(), approval.getProcTaskId(), approval.getLocalVariables());
        // 添加流程关联用户信息
        sysUser.getParams().put("userType", ProcUserType.ASSIGNEE.getCode());
        ruUserService.addProcUserinst(approval.getProcDefId(), approval.getProcInstId(), Arrays.asList(sysUser));

        return false;
    }

    @Override
    @Transactional
    public boolean delegate(String instanceId, String userId, String delegateToUser) {
        return false;
    }

    @Override
    @Transactional
    public boolean cancel(String instanceId, String deleteReason) {
        return false;
    }

    @Override
    @Transactional
    public boolean suspendOrActive(String instanceId, String suspendState) {
        return false;
    }

    @Override
    public List<ProcessApplyInfo> selectApplyList(ProcessApplyInfo applyInfo, SysUser sysUser) {
        List<ProcessApplyInfo> list = new ArrayList<>();
        list.add(new ProcessApplyInfo().setTitle("插入数据").setProcKey("123").setStartUser(sysUser).setBusiKey("123"));
        list.add(new ProcessApplyInfo().setTitle("查询数据").setProcKey("123").setStartUser(sysUser).setBusiKey("1234"));
        list.add(new ProcessApplyInfo().setTitle("删除数据").setProcKey("123").setStartUser(sysUser).setBusiKey("1235"));
        list.add(new ProcessApplyInfo().setTitle("更新数据").setProcKey("123").setStartUser(sysUser).setBusiKey("1233"));
        return list;
    }

    @Override
    public List<ProcessTaskInfo> selectTodoTasks(ProcessTaskInfo taskInfo, SysUser sysUser) {
        List<ProcessTaskInfo> list = new ArrayList<>();
        return list;
    }

    @Override
    public boolean handleTodoTask(ProcessTaskInfo taskInfo) {
        return false;
    }

    @Override
    public List<ProcessTaskInfo> selectEntrustTasks(ProcessTaskInfo taskInfo, SysUser sysUser) {
        List<ProcessTaskInfo> list = new ArrayList<>();
        return list;
    }

    @Override
    public List<ProcessTaskInfo> selectDoneTasks(ProcessTaskInfo taskInfo, SysUser sysUser) {
        List<ProcessTaskInfo> list = new ArrayList<>();
        return list;
    }

    @Override
    public List<ProcessTaskInfo> selectCompletedTasks(ProcessTaskInfo taskInfo, SysUser sysUser) {
        return null;
    }

    @Override
    public boolean cancelApplyList(String ids) {
        return false;
    }

    @Override
    public boolean refuseTodoTask(Long taskId) {
        return false;
    }

    @Override
    public boolean entrustTodoTask(Long taskId, Long userId) {
        return false;
    }

    @Override
    public boolean signTodoTask(Long taskId, Long userId) {
        return false;
    }

    @Override
    public ProcessTaskInfo getDoneTaskInfo(Long taskId) {
        return null;
    }

    @Override
    public boolean checkIsFirstNode(Long procInstId) {
        return false;
    }

    @Override
    public boolean checkWhetherCanCancel(Long procInstId) {
        return false;
    }


}
